import Router from "koa-router";
import { pool } from "../../config/database";
import { generateToken } from "../../utils/jwt";
import { hashPassword, comparePassword } from "../../utils/hash";
import { authMiddleware } from "../../middleware/auth";
import { RowDataPacket, ResultSetHeader } from "mysql2";
import {
  ApiResponse,
  User,
  UserLoginInput,
  UserRegisterInput,
} from "../../types";
import { getRealPublicIP, getLocationFromAmap } from "../Amap/ip";

const router = new Router({ prefix: "/api/auth" });

// 用户注册
router.post("/register", async (ctx) => {
  try {
    const { email, password, username, nickname } = ctx.request
      .body as UserRegisterInput;

    if (!email || !password) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "邮箱和密码不能为空",
      } as ApiResponse;
      return;
    }

    // 检查邮箱是否已存在
    const [existingUsers] = (await pool.execute(
      "SELECT id FROM users WHERE email = ? OR username = ?",
      [email, username || ""]
    )) as [RowDataPacket[], any];

    if (existingUsers.length > 0) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "该邮箱或用户名已被注册",
      } as ApiResponse;
      return;
    }

    // 创建新用户
    const hashedPassword = await hashPassword(password);
    const [result] = (await pool.execute(
      "INSERT INTO users (email, password, username, nickname) VALUES (?, ?, ?, ?)",
      [email, hashedPassword, username || email.split("@")[0], nickname || null]
    )) as [ResultSetHeader, any];

    // 获取创建的用户信息
    const [users] = (await pool.execute(
      "SELECT id, email, username, nickname, avatar, role, created_at, updated_at FROM users WHERE id = ?",
      [result.insertId]
    )) as [RowDataPacket[], any];

    const user = users[0] as User;
    const token = generateToken({
      id: user.id,
      email: user.email,
      username: user.username,
      role: user.role,
    });

    ctx.body = {
      success: true,
      data: {
        token,
        user,
      },
      message: "注册成功",
    } as ApiResponse;
  } catch (error) {
    console.error("注册失败:", error);
    ctx.status = 500;
    ctx.body = {
      success: false,
      message: "注册失败，请稍后重试",
    } as ApiResponse;
  }
});

// 用户登录
router.post("/login", async (ctx) => {
  try {
    const { email, password } = ctx.request.body as UserLoginInput;

    if (!email || !password) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "账号和密码不能为空",
      } as ApiResponse;
      return;
    }

    // 判断输入类型并构建查询条件
    let whereClause = "";
    let searchValue = email.trim();

    // 手机号格式验证（11位数字且以1开头）
    const isPhone = /^1[3-9]\d{9}$/.test(searchValue);
    // 邮箱格式验证
    const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(searchValue);

    if (isPhone) {
      whereClause = "phone = ?";
    } else if (isEmail) {
      whereClause = "email = ?";
    } else {
      // 默认当作用户名处理
      whereClause = "username = ?";
    }

    // 查找用户
    const [users] = (await pool.execute(
      `SELECT id, email, password, username, nickname, phone, avatar, role, created_at, updated_at FROM users WHERE ${whereClause}`,
      [searchValue]
    )) as [RowDataPacket[], any];

    if (users.length === 0) {
      ctx.status = 401;
      ctx.body = {
        success: false,
        message: "账号或密码错误",
      } as ApiResponse;
      return;
    }

    const user = users[0];

    // 验证密码
    const isValidPassword = await comparePassword(password, user.password);
    if (!isValidPassword) {
      ctx.status = 401;
      ctx.body = {
        success: false,
        message: "账号或密码错误",
      } as ApiResponse;
      return;
    }

    // 生成token
    const token = generateToken({
      id: user.id,
      email: user.email,
      username: user.username,
      role: user.role,
    });

    // 移除密码字段
    const { password: _, ...userWithoutPassword } = user;
    //登录成功后获取loginIp,loginIpContent
    const loginIp = await getRealPublicIP();//获取登录ip
    const ipContent = await getLocationFromAmap(loginIp);//获取登录ip的详细信息
    const adcode = (ipContent as any).adcode.length > 0 ? (ipContent as any).adcode : ""; //获取登录ip的adcode
    const rectangle = (ipContent as any).rectangle.length > 0 ? (ipContent as any).rectangle : "";//获取登录ip的矩形
    const city = (ipContent as any).city.length > 0 ? (ipContent as any).city : "";//获取登录ip的城市
    const province = (ipContent as any).province.length > 0 ? (ipContent as any).province : "";//获取登录ip的省份
    const loginIpContent = province + city;//获取登录ip的省份和城市
    let ipinfo;
    if (loginIpContent == "") {
      ipinfo = '该IP不属于中国大陆'
    } else {
      ipinfo = loginIpContent
    }
    await pool.execute(
      "UPDATE users SET loginIp = ?, loginIpContent = ?, last_login_at = CURRENT_TIMESTAMP WHERE id = ?",
      [loginIp, ipinfo, user.id]
    );

    //并插入ip表
    await pool.execute(
      "INSERT INTO ip_addresses (ip, province, city, userId,adcode,rectangle, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",
      [loginIp, province, city, user.id, adcode, rectangle, new Date()]
    );
    ctx.body = {
      success: true,
      data: {
        token,
        user: userWithoutPassword as User,
      },
      message: "登录成功",
    } as ApiResponse;
  } catch (error) {
    console.error("登录失败:", error);
    ctx.status = 500;
    ctx.body = {
      success: false,
      message: "登录失败，请稍后重试",
    } as ApiResponse;
  }
});

// 获取用户登录信息
router.get("/loginInfo", authMiddleware, async (ctx) => {
  const userId = ctx.state.user.id as number;
  const [ipInfo] = (await pool.execute(
    "SELECT ip, province, city, created_at FROM ip_addresses WHERE userId = ? ORDER BY created_at DESC LIMIT 10",
    [userId]
  )) as [RowDataPacket[], any];
  ctx.body = {
    success: true,
    data: ipInfo,
  } as ApiResponse;
});

// 获取当前用户信息
router.get("/me", authMiddleware, async (ctx) => {
  try {
    const userId = ctx.state.user.id as number;

    const [users] = (await pool.execute(
      "SELECT id, email, username, nickname, phone, avatar, role, created_at, updated_at, last_login_at FROM users WHERE id = ?",
      [userId]
    )) as [RowDataPacket[], any];

    if (users.length === 0) {
      ctx.status = 404;
      ctx.body = {
        success: false,
        message: "用户不存在",
      } as ApiResponse;
      return;
    }
    ctx.body = {
      success: true,
      data: users[0] as User,
    } as ApiResponse;
  } catch (error) {
    console.error("获取用户信息失败:", error);
    ctx.status = 500;
    ctx.body = {
      success: false,
      message: "获取用户信息失败",
    } as ApiResponse;
  }
});

// 更新用户资料
router.put("/profile", authMiddleware, async (ctx) => {
  try {
    const userId = ctx.state.user.id as number;
    const requestBody = ctx.request.body as any;
    const { username, nickname, phone, avatar } = requestBody;

    const fields = [];
    const values = [];

    if (username !== undefined) {
      fields.push("username = ?");
      values.push(username);
    }
    if (nickname !== undefined) {
      fields.push("nickname = ?");
      values.push(nickname);
    }
    if (phone !== undefined) {
      fields.push("phone = ?");
      values.push(phone);
    }
    if (avatar !== undefined) {
      fields.push("avatar = ?");
      values.push(avatar);
    }

    if (fields.length === 0) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "没有需要更新的字段",
      } as ApiResponse;
      return;
    }

    fields.push("updated_at = CURRENT_TIMESTAMP");
    values.push(userId);

    await pool.execute(
      `UPDATE users SET ${fields.join(", ")} WHERE id = ?`,
      values
    );

    // 获取更新后的用户信息
    const [users] = (await pool.execute(
      "SELECT id, email, username, nickname, phone, avatar, role, created_at, updated_at, last_login_at FROM users WHERE id = ?",
      [userId]
    )) as [RowDataPacket[], any];

    ctx.body = {
      success: true,
      data: users[0] as User,
      message: "用户信息更新成功",
    } as ApiResponse;
  } catch (error) {
    console.error("更新用户信息失败:", error);
    ctx.status = 500;
    ctx.body = {
      success: false,
      message: "更新用户信息失败",
    } as ApiResponse;
  }
});

// 修改密码
router.put("/password", authMiddleware, async (ctx) => {
  try {
    const userId = ctx.state.user.id as number;
    const requestBody = ctx.request.body as any;
    const { currentPassword, newPassword } = requestBody;

    if (!currentPassword || !newPassword) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "当前密码和新密码不能为空",
      } as ApiResponse;
      return;
    }

    // 获取当前密码
    const [users] = (await pool.execute(
      "SELECT password FROM users WHERE id = ?",
      [userId]
    )) as [RowDataPacket[], any];

    if (users.length === 0) {
      ctx.status = 404;
      ctx.body = {
        success: false,
        message: "用户不存在",
      } as ApiResponse;
      return;
    }

    // 验证当前密码
    const isValidPassword = await comparePassword(
      currentPassword,
      users[0].password
    );
    if (!isValidPassword) {
      ctx.status = 400;
      ctx.body = {
        success: false,
        message: "当前密码错误",
      } as ApiResponse;
      return;
    }

    // 更新密码
    const hashedNewPassword = await hashPassword(newPassword);
    await pool.execute(
      "UPDATE users SET password = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?",
      [hashedNewPassword, userId]
    );

    ctx.body = {
      success: true,
      message: "密码修改成功",
    } as ApiResponse;
  } catch (error) {
    console.error("修改密码失败:", error);
    ctx.status = 500;
    ctx.body = {
      success: false,
      message: "修改密码失败",
    } as ApiResponse;
  }
});

// 登出
router.post("/logout", authMiddleware, async (ctx) => {
  ctx.body = {
    success: true,
    message: "退出登录成功",
  } as ApiResponse;
});

export default router;
